<template>
  <div class="frame-tabs">
    <!-- tabs -->
    <div class="frame-tabs-scroll hide-scroll" ref="tabScrollRef">
      <div ref="list" class="frame-tabs-list">
        <frame-tab
          v-for="tab in tabs"
          :key="`${tab.id}`"
          :tab="tab"
          @jump="$emit('jump', $event)"
          @reload="$emit('reload', $event)"
          @close="$emit('close', $event)"
        />
      </div>
    </div>
    <el-popover
      placement="bottom"
      :visible.sync="tabPopperVisible"
      popper-class="tab-list-popper"
      width="240"
    >
      <div class="tab-list-wrap">
        <div class="search-row">
          <el-input
            v-model="tabKeyword"
            class="tab-search-input"
            :placeholder="$t('frame.frameTabs.searchTab')"
          >
            <i class="el-icon-search" slot="prefix"></i>
          </el-input>
        </div>
        <template v-if="showTabsList.length">
          <div class="title">{{ $t('frame.frameTabs.opendTab') }}</div>
          <div class="tab-list">
            <div
              class="tab-list-item"
              v-for="tab in showTabsList"
              :key="tab.id"
              @click="jumpTab(tab)"
            >
              <span class="tab-title">{{ tab.originTitle }}</span>
              <span
                v-if="tab.closeable"
                class="base-btn base-btn--icon base-btn--circle close-icon"
                @click.stop="closeTab(tab)"
              >
                <i class="iconfont icon-close"></i>
              </span>
            </div>
          </div>
        </template>
        <div v-else class="empty-record">{{ $t('common.base.tip.emptySearchRecord') }}</div>
      </div>
      <button slot="reference" class="base-btn base-btn--icon tab-menu-btn" v-track="$track.formatParams('NAV_TABS_DROPDOWN')">
        <i class="iconfont icon-more"></i>
      </button>
    </el-popover>

    <el-popover 
      placement="bottom" 
      trigger="click" 
      popper-class="close-menu-entry-popper"
    >
      <button class="base-btn base-btn--icon tab-menu-btn" slot="reference">
        <i class="iconfont icon-daohang menu-icon"></i>
      </button>

      <div class="close-menu-entry-popper-list">
        <div class="close-menu-entry-popper-list-item" v-if="currentTab && !currentTab.isHome" @click="chooseMenuItem('self')">{{ $t('frame.frameTabs.closeTab[0]') }}</div>
        <div class="close-menu-entry-popper-list-item" v-track="$track.formatParams('NAV_CLOSE_ALL_TABS')" @click="chooseMenuItem('all')">{{ $t('frame.frameTabs.closeTab[1]') }}</div>
        <div class="close-menu-entry-popper-list-item" v-track="$track.formatParams('NAV_CLOSE_OTHER_TABS')" @click="chooseMenuItem('other')">{{ $t('frame.frameTabs.closeTab[2]') }}</div>
      </div>
    
    </el-popover>
  </div>
</template>

<script>
import { defineComponent, ref, computed, unref, nextTick } from 'vue';
import FrameTab from './FrameTab';

// use scroll
function useSmoothScroll(elRef, direction = 'vertical') {
  const diretions = {
    horizontal: 'scrollLeft',
    vertical: 'scrollTop',
  };
  const scrollDirection = diretions[direction];

  if (!scroll) {
    throw new Error('请输入正确的滚动方向！');
  }

  function scrollTo(target, current = unref(elRef)?.[scrollDirection]) {
    if (!unref(elRef)) return;
    if (target < 0) target = 0;
    let needScrollTop = target - current;
    const dist = Math.ceil(needScrollTop / 5);
    let now = current + dist;
    requestAnimationFrame(() => {
      // 一次调用滑动帧数，每次调用会不一样
      unref(elRef)[scrollDirection] = now;
      // 如果移动幅度小于十个像素，直接移动，否则递归调用，实现动画效果
      if (needScrollTop > 10 || needScrollTop < -10) {
        scrollTo(target, now);
      } else {
        unref(elRef)[scrollDirection] = target;
      }
    });
  }

  return {
    scrollTo,
  };
}

export default defineComponent({
  name: 'frame-tab-group',
  components: {
    FrameTab,
  },
  props: {
    tabs: {
      type: Array,
      default: () => [],
    },
  },
  setup(props, { emit }) {
    const tabScrollRef = ref();
    const tabKeyword = ref('');
    const tabPopperVisible = ref(false);
    const { scrollTo } = useSmoothScroll(tabScrollRef, 'horizontal');
    const currentTab = computed(() => props.tabs.find(item => item.show));

    const showTabsList = computed(() => {
      const k = tabKeyword.value.trim();
      if (k === '') {
        return props.tabs;
      }
      return props.tabs.filter(item =>
        item.loading
          ? item.originTitle.indexOf(k) > -1
          : item.title.indexOf(k) > -1
      );
    });

    // 切换tab
    function jumpTab(tab) {
      emit('jump', tab);
      tabPopperVisible.value = false;
      scrollToTab(tab);
    }

    // 关闭tab
    function closeTab(tab) {
      emit('close', tab);
    }

    // 转义url中css无法识别字符
    function escapeSelector(selector) {
      return selector.replace(/(&)/g, '\\\$1');
    }

    function scrollToTab(tab) {
      if (!tabScrollRef.value) return;
      const { offsetWidth } = tabScrollRef.value;
      const select = escapeSelector(`#tab_${tab.id}`)
      const tabEl = tabScrollRef.value.querySelector(select);
      const position = tabEl.offsetLeft;
      // 计算目标位置 （在视线内不需要滚动， 滚动至容器中间区域）
      scrollTo(position - offsetWidth / 2);
    }

    // 关闭所有
    function closeAll() {
      emit('closeAll');
      // const homeTab = props.tabs[0];
      // if (homeTab && homeTab.isHome) {
      //   emit('update:tabs', [homeTab]);
      //   homeTab.show = true;
      // } else {
      //   emit('update:tabs', []);
      // }
    }

    // 关闭其他
    async function closeOther() {
      const index = props.tabs.findIndex(item =>item.show)
      emit('closeOther', index);
      // const index = props.tabs.findIndex(item =>!item.isHome && !item.show)
      // if(index === -1) return
      // const tabs = [...props.tabs]
      // tabs.splice(index, 1); // 同时删除tab导致元素位置变动会重新渲染iframe

      // emit(
      //   'update:tabs',
      //   tabs
      // );
      // await nextTick()
      // closeOther()
    }

    // 关闭当前
    function closeSelf() {
      if (currentTab.value.isHome) return;
      const tabs = props.tabs.filter(item => !item.show);
      emit('update:tabs', tabs);
      emit('jump', tabs[tabs.length - 1]);
    }

    function chooseMenuItem(command) {
      const map = {
        self: closeSelf,
        other: closeOther,
        all: closeAll,
      };
      map[command]();
    }

    return {
      tabScrollRef,
      tabPopperVisible,
      tabKeyword,
      showTabsList,
      currentTab,
      jumpTab,
      closeTab,
      scrollToTab,
      chooseMenuItem,
    };
  },
});
</script>

<style lang="scss">
.frame-tabs {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  flex-flow: row nowrap;
  overflow: hidden;
  user-select: none;

  .frame-tabs-scroll {
    margin-right: 16px;
    position: relative;
    flex: 1;
    height: 100%;
    display: flex;
    align-items: flex-end;
    overflow: auto;
    .frame-tabs-list {
      width: 0;
      white-space: nowrap;
    }
  }
  .frame-tabs-border {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    border-bottom: 1px solid #f2f2f2;
  }

  .tab-dropdown-btn {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    outline: none;
    border: none;
    border-radius: 2px;
    background: #f5f5f5;
  }
  .tab-menu-btn {
    margin-left: 8px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;

    i {
      font-size: 18px;
    }

    .menu-icon {
      font-size: 16px;
    }

    &:hover {
      background: #f5f5f5;
    }
  }
}
.tab-list-popper {
  padding: 0 0 12px 0;
  user-select: none;
  width: 240px;

  .tab-list-wrap {
    font-size: 12px;
    .search-row {
      padding: 12px 12px 8px 12px;
    }
    .tab-search-input {
      // padding: 6px 12px;
      input {
        padding-left: 16px;
        height: 22px;
        border: none;
      }
      .el-input__prefix {
        left: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        i {
          color: #595959;
          font-size: 12px;
        }
      }
    }

    .title {
      padding: 0 12px;
      height: 36px;
      line-height: 36px;
      color: $text-color-secondary;
      background: #f5f5f5;
    }

    .tab-list {
      max-height: 450px;
      overflow-y: auto;
      .tab-list-item {
        padding: 0 12px;
        height: 32px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        cursor: pointer;
        &:hover {
          background: #fafafa;
        }
        .tab-title {
          flex: 1;
          font-size: 14px;
          @include text-ellipsis();
        }
        .close-icon {
        }
      }
    }

    .empty-record {
      margin-top: 20px;
      text-align: center;
      font-size: 14px;
      color: $text-color-secondary;
    }
  }
}

.close-menu-entry-popper {
  padding: 4px 0;
  min-width: 110px;
  &-list {
    &-item {
      padding: 4px 12px;
      @include text-ellipsis();
      cursor: pointer;
      &:hover {
        background: #fafafa;
      }
    }
  }
}
</style>
